'use strict';

const Service = require('egg').Service;

/**
 * 评分规则服务类
 * 处理评分规则的管理、启用和计算
 */
class ScoringRuleService extends Service {
  /**
   * 获取所有规则
   * 按规则组和作者人数排序
   * @returns {Promise<Array>} 规则列表
   */
  async findAll() {
    const result = await this.app.mysql.query(
      'SELECT * FROM tb_scoring_rule ORDER BY rule_group ASC, num_authors ASC'
    );
    return result;
  }

  /**
   * 根据ID获取规则
   * @param {number} id - 规则ID
   * @returns {Promise<Object|null>} 规则信息，不存在时返回null
   */
  async findById(id) {
    const result = await this.app.mysql.query(
      'SELECT * FROM tb_scoring_rule WHERE rule_id = ?',
      [id]
    );
    return result[0];
  }

  /**
   * 创建新规则
   * @param {Object} data - 规则数据
   * @param {number} data.rule_group - 规则组
   * @param {number} data.num_authors - 作者人数（1-3）
   * @param {number} data.author1_weight - 作者1权重（0-1）
   * @param {number} [data.author2_weight] - 作者2权重（0-1）
   * @param {number} [data.author3_weight] - 作者3权重（0-1）
   * @returns {Promise<Object|{error: string}>} 创建的规则信息，或错误信息
   */
  async create(data) {
    // 检查同一规则组下是否已存在相同作者人数的规则
    const exists = await this.checkDuplicate(data.rule_group, data.num_authors);
    if (exists) {
      return { error: 'duplicate_rule' };
    }

    const result = await this.app.mysql.insert('tb_scoring_rule', {
      rule_group: data.rule_group,
      num_authors: data.num_authors,
      author1_weight: data.author1_weight,
      author2_weight: data.author2_weight,
      author3_weight: data.author3_weight,
    });
    
    return await this.findById(result.insertId);
  }

  /**
   * 更新规则
   * @param {number} id - 规则ID
   * @param {Object} data - 更新数据
   * @param {number} data.rule_group - 规则组
   * @param {number} data.num_authors - 作者人数
   * @param {number} data.author1_weight - 作者1权重
   * @param {number} [data.author2_weight] - 作者2权重
   * @param {number} [data.author3_weight] - 作者3权重
   * @returns {Promise<Object|{error: string}|null>} 更新后的规则信息，或错误信息，不存在时返回null
   */
  async update(id, data) {
    // 先检查记录是否存在
    const rule = await this.findById(id);
    if (!rule) {
      return null;
    }

    // 如果修改了规则组或作者人数，需要检查是否会导致重复
    if (data.rule_group !== rule.rule_group || data.num_authors !== rule.num_authors) {
      const exists = await this.checkDuplicate(data.rule_group, data.num_authors, id);
      if (exists) {
        return { error: 'duplicate_rule' };
      }
    }

    // 执行更新
    await this.app.mysql.update('tb_scoring_rule', {
      rule_group: data.rule_group,
      num_authors: data.num_authors,
      author1_weight: data.author1_weight,
      author2_weight: data.author2_weight,
      author3_weight: data.author3_weight,
    }, {
      where: { rule_id: id }
    });
    
    // 返回更新后的记录
    return await this.findById(id);
  }

  /**
   * 删除规则
   * @param {number} id - 规则ID
   * @returns {Promise<Object|null>} 删除的规则信息，不存在时返回null
   */
  async delete(id) {
    // 先检查记录是否存在
    const rule = await this.findById(id);
    if (!rule) {
      return null;
    }

    // 执行删除
    await this.app.mysql.delete('tb_scoring_rule', {
      rule_id: id,
    });

    // 返回被删除的记录
    return rule;
  }

  /**
   * 检查规则是否重复
   * 同一规则组下不能有相同作者人数的规则
   * @param {number} ruleGroup - 规则组
   * @param {number} numAuthors - 作者人数
   * @param {number} [excludeId] - 排除的规则ID（用于更新时检查）
   * @returns {Promise<boolean>} 是否存在重复规则
   */
  async checkDuplicate(ruleGroup, numAuthors, excludeId = null) {
    let sql = 'SELECT COUNT(*) as count FROM tb_scoring_rule WHERE rule_group = ? AND num_authors = ?';
    const params = [ruleGroup, numAuthors];

    if (excludeId) {
      sql += ' AND rule_id != ?';
      params.push(excludeId);
    }

    const result = await this.app.mysql.query(sql, params);
    return result[0].count > 0;
  }

  /**
   * 启用规则组
   * 同时只能有一个规则组被启用
   * @param {number} ruleGroupId - 要启用的规则组ID
   * @returns {Promise<Array>} 启用的规则组中的所有规则
   */
  async enable(ruleGroupId) {
    // 先将所有规则组设置为未启用
    await this.app.mysql.update('tb_scoring_rule', {
      is_enabled: 0
    }, {
      where: {}  // 不加条件，更新所有记录
    });

    // 再启用指定的规则组
    await this.app.mysql.update('tb_scoring_rule', {
      is_enabled: 1
    }, {
      where: { rule_group: ruleGroupId }
    });

    // 返回更新后的规则组
    const result = await this.app.mysql.query(
      'SELECT * FROM tb_scoring_rule WHERE rule_group = ? ORDER BY num_authors',
      [ruleGroupId]
    );
    return result;
  }

  /**
   * 获取当前启用的规则组
   * @returns {Promise<Array>} 当前启用的规则组中的所有规则
   */
  async getEnabledGroup() {
    const result = await this.app.mysql.query(
      'SELECT * FROM tb_scoring_rule WHERE is_enabled = 1 ORDER BY num_authors'
    );
    return result;
  }

  /**
   * 获取分组后的规则列表
   * 按规则组分组，返回二维数组
   * @returns {Promise<Array>} 分组后的规则列表，形如 [[规则组1的规则], [规则组2的规则]]
   */
  async findAllGrouped() {
    // 先获取所有规则，按规则组和作者人数排序
    const sql = `
      SELECT * 
      FROM tb_scoring_rule 
      ORDER BY rule_group ASC, num_authors ASC
    `;
    const rules = await this.app.mysql.query(sql);

    // 按规则组分组
    const groupedRules = [];
    let currentGroup = [];
    let currentGroupId = null;

    rules.forEach(rule => {
      if (currentGroupId !== rule.rule_group) {
        if (currentGroup.length > 0) {
          groupedRules.push(currentGroup);
        }
        currentGroup = [rule];
        currentGroupId = rule.rule_group;
      } else {
        currentGroup.push(rule);
      }
    });

    // 添加最后一组
    if (currentGroup.length > 0) {
      groupedRules.push(currentGroup);
    }

    return groupedRules;
  }
}

module.exports = ScoringRuleService; 